<?php
declare(strict_types=1);

namespace app\shop\logic;

use app\shop\exception\FailException;
use app\shop\library\ShopHelper;
use app\shop\model\user\UserAddressModel;
use Exception;
use think\Model;

class UserAddressLogic extends BaseLogic
{
    /**
     * 列表
     * @param array $params
     * @return array
     */
    public function list(array $params): array
    {
        $query = UserAddressModel::getQuery();

        $query->where('user_id', $params['user_id']);

        $query->withoutField(['create_time', 'update_time', 'zip']);

        $query->order('is_default', 'desc');

        return UserAddressModel::paginateListQuery($query, true);
    }

    /**
     * 详情
     * @param array $params
     * @return array
     */
    public function detail(array $params): array
    {
        $query = UserAddressModel::getQuery();

        $query->where([
            ['id', '=', $params['id']],
            ['user_id', '=', $params['user_id']]
        ]);

        return $query->withoutField(['create_time', 'update_time'])->findOrEmpty()->toArray();
    }

    /**
     * 添加
     * @param array $params
     * @return UserAddressModel|Model
     * @throws FailException
     */
    public function add(array $params): UserAddressModel|Model
    {
        [
            'province'      => $params['province'],
            'city'          => $params['city'],
            'county'        => $params['county'],
            'full_location' => $fullLocation
        ] = $this->getRegionId($params);

        if (!isset($params['full_location'])) {
            $params['full_location'] = $fullLocation;
        }

        try {
            $this->handleDefault($params);
            return UserAddressModel::create($params);
        } catch (Exception $e) {
            throw new FailException('添加地址失败', null, $e);
        }
    }

    /**
     * 修改
     * @param array $data
     * @return UserAddressModel
     * @throws FailException
     */
    public function edit(array $data): UserAddressModel
    {
        [
            'province'      => $data['province'],
            'city'          => $data['city'],
            'county'        => $data['county'],
            'full_location' => $fullLocation
        ] = $this->getRegionId($data);

        if (!isset($data['full_location'])) {
            $data['full_location'] = $fullLocation;
        }

        try {
            $this->handleDefault($data);
            return UserAddressModel::update($data, ['id' => $data['id']]);
        } catch (Exception $e) {
            throw new FailException('修改地址失败', null, $e);
        }
    }

    /**
     * 设置默认地址
     * @param array $params
     */
    public function handleDefault(array $params): void
    {
        if ($params['is_default']) {
            $where = [
                ['is_default', '=', 1],
            ];
            UserAddressModel::where($where)->update(['is_default' => 0]);
        }
    }

    /**
     * 删除
     * @param array|string $id
     * @return string
     * @throws FailException
     */
    public function delete(array|string $id): string
    {
        if (!UserAddressModel::where(['id' => $id])->delete()) {
            throw new FailException('删除地址失败', null);
        }

        return '删除成功';
    }

    /**
     * 解析省市区ID
     * @param array $params
     * @return int[]
     * @throws FailException
     */
    private function getRegionId(array $params): array
    {
        $areas     = array_column($areaData = ShopHelper::get_all_area(), 'name', 'id');
        $areaCodes = array_keys($areas);

        $provinceIndex = array_search($params['province'], $areaCodes);
        $provinceId    = $areaData[$provinceIndex]['id'] ?? 0;
        $cityIndex     = array_search($params['city'], $areaCodes);
        $cityId        = $areaData[$cityIndex]['id'] ?? 0;
        $countyIndex   = array_search($params['county'], $areaCodes);
        $countyId      = $areaData[$countyIndex]['id'] ?? 0;

        if ($provinceId == 0 || $cityId == 0 || $countyId == 0) {
            throw new FailException('当前省市区数据未录入系统,请联系管理员');
        }

        return [
            'province'      => $provinceId,
            'city'          => $cityId,
            'county'        => $countyId,
            'full_location' => $areas[$params['province']] . ' ' . $areas[$params['city']] . ' ' . $areas[$params['county']],
        ];
    }
}
